package cn.jbolt.core.json;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONScanner;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson.util.TypeUtils;

import java.lang.reflect.Type;
import java.math.BigDecimal;

/**
 * 自定义 {@link java.sql.Time} 时间类型反序列化规则。<br>
 * 支持格式为 <b>HH:ss</b>
 *
 * @ClassName: SqlTimeDeserializer
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年3月7日
 */
public class JBoltSqlTimeDeserializer implements ObjectDeserializer {

	public final static JBoltSqlTimeDeserializer instance = new JBoltSqlTimeDeserializer();

	@SuppressWarnings("unchecked")
	@Override
	public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
		JSONLexer lexer = parser.getLexer();
		Object val = parser.parse();
		if (val == null) {
			return null;
		}
		if (val instanceof java.sql.Time) {
			return (T) val;
		} else if (val instanceof BigDecimal) {
			return (T) new java.sql.Time(TypeUtils.longValue((BigDecimal) val));
		} else if (val instanceof Number) {
			return (T) new java.sql.Time(((Number) val).longValue());
		} else if (val instanceof String) {
			String strVal = (String) val;
			if (strVal.length() == 0) {
				return null;
			}

			long longVal;
			JSONScanner dateLexer = new JSONScanner(strVal);
			if (dateLexer.scanISO8601DateIfMatch()) {
				longVal = dateLexer.getCalendar().getTimeInMillis();
			} else {
				boolean isDigit = true;
				for (int i = 0; i < strVal.length(); ++i) {
					char ch = strVal.charAt(i);
					if (ch < '0' || ch > '9') {
						isDigit = false;
						break;
					}
				}
				if (!isDigit) {
					dateLexer.close();
					if (strVal.indexOf(":") == 2 && strVal.length() == 5) {
						return (T) java.sql.Time.valueOf(val + ":00");
					}
					return (T) java.sql.Time.valueOf(strVal);
				}

				longVal = Long.parseLong(strVal);
			}
			dateLexer.close();
			return (T) new java.sql.Time(longVal);
		}
		throw new JSONException("parse error");
	}

	@Override
	public int getFastMatchToken() {
		return JSONToken.LITERAL_INT;
	}
}
